home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume24 / gnucalc / part29 < prev    next >
Encoding:
Text File  |  1991-10-31  |  55.2 KB  |  1,764 lines

  1. Newsgroups: comp.sources.misc
  2. From: daveg@synaptics.com (David Gillespie)
  3. Subject:  v24i077:  gnucalc - GNU Emacs Calculator, v2.00, Part29/56
  4. Message-ID: <1991Oct31.214331.2109@sparky.imd.sterling.com>
  5. X-Md4-Signature: d6ea4cba7bb16d7278d5304d42f92a3c
  6. Date: Thu, 31 Oct 1991 21:43:31 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: daveg@synaptics.com (David Gillespie)
  10. Posting-number: Volume 24, Issue 77
  11. Archive-name: gnucalc/part29
  12. Environment: Emacs
  13. Supersedes: gmcalc: Volume 13, Issue 27-45
  14.  
  15. ---- Cut Here and unpack ----
  16. #!/bin/sh
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file calc-units.el continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 29; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping calc-units.el'
  34. else
  35. echo 'x - continuing file calc-units.el'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'calc-units.el' &&
  37. X                 (setq uoldname (concat "1" uoldname)))
  38. X                 (math-read-expr uoldname))))))
  39. X       (if (eq (car-safe uold) 'error)
  40. X           (error "Bad format in units expression: %s" (nth 1 uold)))
  41. X       (setq expr (math-mul expr uold))))
  42. X     (or new-units
  43. X     (setq new-units (read-string (if uoldname
  44. X                      (concat "Old units: "
  45. X                          uoldname
  46. X                          ", new units: ")
  47. X                    "New units: "))))
  48. X     (if (string-match "\\` */" new-units)
  49. X     (setq new-units (concat "1" new-units)))
  50. X     (setq units (math-read-expr new-units))
  51. X     (if (eq (car-safe units) 'error)
  52. X     (error "Bad format in units expression: %s" (nth 2 units)))
  53. X     (let ((unew (math-units-in-expr-p units t))
  54. X       (std (and (eq (car-safe units) 'var)
  55. X             (assq (nth 1 units) math-standard-units-systems))))
  56. X       (if std
  57. X       (calc-enter-result 1 "cvun" (math-simplify-units
  58. X                    (math-to-standard-units expr
  59. X                                (nth 1 std))))
  60. X     (or unew
  61. X         (error "No units specified"))
  62. X     (calc-enter-result 1 "cvun"
  63. X                (math-convert-units
  64. X                 expr units
  65. X                 (and uoldname (not (equal uoldname "1")))))))))
  66. )
  67. X
  68. (defun calc-autorange-units (arg)
  69. X  (interactive "P")
  70. X  (calc-wrapper
  71. X   (calc-change-mode 'calc-autorange-units arg nil t)
  72. X   (message (if calc-autorange-units
  73. X        "Adjusting target unit prefix automatically."
  74. X          "Using target units exactly.")))
  75. )
  76. X
  77. (defun calc-convert-temperature (&optional old-units new-units)
  78. X  (interactive)
  79. X  (calc-slow-wrapper
  80. X   (let ((expr (calc-top-n 1))
  81. X     (uold nil)
  82. X     (uoldname nil)
  83. X     unew)
  84. X     (setq uold (or old-units
  85. X            (let ((units (math-single-units-in-expr-p expr)))
  86. X              (if units
  87. X              (if (consp units)
  88. X                  (list 'var (car units)
  89. X                    (intern (concat "var-"
  90. X                            (symbol-name
  91. X                             (car units)))))
  92. X                (error "Not a pure temperature expression"))
  93. X            (math-read-expr
  94. X             (setq uoldname (read-string
  95. X                     "Old temperature units: ")))))))
  96. X     (if (eq (car-safe uold) 'error)
  97. X     (error "Bad format in units expression: %s" (nth 2 uold)))
  98. X     (or (math-units-in-expr-p expr nil)
  99. X     (setq expr (math-mul expr uold)))
  100. X     (setq unew (or new-units
  101. X            (math-read-expr
  102. X             (read-string (if uoldname
  103. X                      (concat "Old temperature units: "
  104. X                          uoldname
  105. X                          ", new units: ")
  106. X                    "New temperature units: ")))))
  107. X     (if (eq (car-safe unew) 'error)
  108. X     (error "Bad format in units expression: %s" (nth 2 unew)))
  109. X     (calc-enter-result 1 "cvtm" (math-simplify-units
  110. X                  (math-convert-temperature expr uold unew
  111. X                                uoldname)))))
  112. )
  113. X
  114. (defun calc-remove-units ()
  115. X  (interactive)
  116. X  (calc-slow-wrapper
  117. X   (calc-enter-result 1 "rmun" (math-simplify-units
  118. X                (math-remove-units (calc-top-n 1)))))
  119. )
  120. X
  121. (defun calc-extract-units ()
  122. X  (interactive)
  123. X  (calc-slow-wrapper
  124. X   (calc-enter-result 1 "rmun" (math-simplify-units
  125. X                (math-extract-units (calc-top-n 1)))))
  126. )
  127. X
  128. (defun calc-explain-units ()
  129. X  (interactive)
  130. X  (calc-wrapper
  131. X   (let ((num-units nil)
  132. X     (den-units nil))
  133. X     (calc-explain-units-rec (calc-top-n 1) 1)
  134. X     (and den-units (string-match "^[^(].* .*[^)]$" den-units)
  135. X      (setq den-units (concat "(" den-units ")")))
  136. X     (if num-units
  137. X     (if den-units
  138. X         (message "%s per %s" num-units den-units)
  139. X       (message "%s" num-units))
  140. X       (if den-units
  141. X       (message "1 per %s" den-units)
  142. X     (message "No units in expression")))))
  143. )
  144. X
  145. (defun calc-explain-units-rec (expr pow)
  146. X  (let ((u (math-check-unit-name expr))
  147. X    pos)
  148. X    (if (and u (not (math-zerop pow)))
  149. X    (let ((name (or (nth 2 u) (symbol-name (car u)))))
  150. X      (if (eq (aref name 0) ?\*)
  151. X          (setq name (substring name 1)))
  152. X      (if (string-match "[^a-zA-Z0-9']" name)
  153. X          (if (string-match "^[a-zA-Z0-9' ()]*$" name)
  154. X          (while (setq pos (string-match "[ ()]" name))
  155. X            (setq name (concat (substring name 0 pos)
  156. X                       (if (eq (aref name pos) 32) "-" "")
  157. X                       (substring name (1+ pos)))))
  158. X        (setq name (concat "(" name ")"))))
  159. X      (or (eq (nth 1 expr) (car u))
  160. X          (setq name (concat (nth 2 (assq (aref (symbol-name
  161. X                             (nth 1 expr)) 0)
  162. X                          math-unit-prefixes))
  163. X                 (if (and (string-match "[^a-zA-Z0-9']" name)
  164. X                      (not (memq (car u) '(mHg gf))))
  165. X                     (concat "-" name)
  166. X                   (downcase name)))))
  167. X      (cond ((or (math-equal-int pow 1)
  168. X             (math-equal-int pow -1)))
  169. X        ((or (math-equal-int pow 2)
  170. X             (math-equal-int pow -2))
  171. X         (if (equal (nth 4 u) '((m . 1)))
  172. X             (setq name (concat "Square-" name))
  173. X           (setq name (concat name "-squared"))))
  174. X        ((or (math-equal-int pow 3)
  175. X             (math-equal-int pow -3))
  176. X         (if (equal (nth 4 u) '((m . 1)))
  177. X             (setq name (concat "Cubic-" name))
  178. X           (setq name (concat name "-cubed"))))
  179. X        (t
  180. X         (setq name (concat name "^"
  181. X                    (math-format-number (math-abs pow))))))
  182. X      (if (math-posp pow)
  183. X          (setq num-units (if num-units
  184. X                  (concat num-units " " name)
  185. X                name))
  186. X        (setq den-units (if den-units
  187. X                (concat den-units " " name)
  188. X                  name))))
  189. X      (cond ((eq (car-safe expr) '*)
  190. X         (calc-explain-units-rec (nth 1 expr) pow)
  191. X         (calc-explain-units-rec (nth 2 expr) pow))
  192. X        ((eq (car-safe expr) '/)
  193. X         (calc-explain-units-rec (nth 1 expr) pow)
  194. X         (calc-explain-units-rec (nth 2 expr) (- pow)))
  195. X        ((memq (car-safe expr) '(neg + -))
  196. X         (calc-explain-units-rec (nth 1 expr) pow))
  197. X        ((and (eq (car-safe expr) '^)
  198. X          (math-realp (nth 2 expr)))
  199. X         (calc-explain-units-rec (nth 1 expr)
  200. X                     (math-mul pow (nth 2 expr)))))))
  201. )
  202. X
  203. (defun calc-simplify-units ()
  204. X  (interactive)
  205. X  (calc-slow-wrapper
  206. X   (calc-with-default-simplification
  207. X    (calc-enter-result 1 "smun" (math-simplify-units (calc-top-n 1)))))
  208. )
  209. X
  210. (defun calc-view-units-table (n)
  211. X  (interactive "P")
  212. X  (and n (setq math-units-table-buffer-valid nil))
  213. X  (let ((win (get-buffer-window "*Units Table*")))
  214. X    (if (and win
  215. X         math-units-table
  216. X         math-units-table-buffer-valid)
  217. X    (progn
  218. X      (bury-buffer (window-buffer win))
  219. X      (let ((curwin (selected-window)))
  220. X        (select-window win)
  221. X        (switch-to-buffer nil)
  222. X        (select-window curwin)))
  223. X      (math-build-units-table-buffer nil)))
  224. )
  225. X
  226. (defun calc-enter-units-table (n)
  227. X  (interactive "P")
  228. X  (and n (setq math-units-table-buffer-valid nil))
  229. X  (math-build-units-table-buffer t)
  230. X  (message (substitute-command-keys "Type \\[calc] to return to the Calculator."))
  231. )
  232. X
  233. (defun calc-define-unit (uname desc)
  234. X  (interactive "SDefine unit name: \nsDescription: ")
  235. X  (calc-wrapper
  236. X   (let ((form (calc-top-n 1))
  237. X     (unit (assq uname math-additional-units)))
  238. X     (or unit
  239. X     (setq math-additional-units
  240. X           (cons (setq unit (list uname nil nil))
  241. X             math-additional-units)
  242. X           math-units-table nil))
  243. X     (setcar (cdr unit) (and (not (and (eq (car-safe form) 'var)
  244. X                       (eq (nth 1 form) uname)))
  245. X                 (not (math-equal-int form 1))
  246. X                 (math-format-flat-expr form 0)))
  247. X     (setcar (cdr (cdr unit)) (and (not (equal desc ""))
  248. X                   desc))))
  249. X  (calc-invalidate-units-table)
  250. )
  251. X
  252. (defun calc-undefine-unit (uname)
  253. X  (interactive "SUndefine unit name: ")
  254. X  (calc-wrapper
  255. X   (let ((unit (assq uname math-additional-units)))
  256. X     (or unit
  257. X     (if (assq uname math-standard-units)
  258. X         (error "\"%s\" is a predefined unit name" uname)
  259. X       (error "Unit name \"%s\" not found" uname)))
  260. X     (setq math-additional-units (delq unit math-additional-units)
  261. X       math-units-table nil)))
  262. X  (calc-invalidate-units-table)
  263. )
  264. X
  265. (defun calc-invalidate-units-table ()
  266. X  (setq math-units-table nil)
  267. X  (let ((buf (get-buffer "*Units Table*")))
  268. X    (and buf
  269. X     (save-excursion
  270. X       (set-buffer buf)
  271. X       (save-excursion
  272. X         (goto-char (point-min))
  273. X         (if (looking-at "Calculator Units Table")
  274. X         (let ((buffer-read-only nil))
  275. X           (insert "(Obsolete) ")))))))
  276. )
  277. X
  278. (defun calc-get-unit-definition (uname)
  279. X  (interactive "SGet definition for unit: ")
  280. X  (calc-wrapper
  281. X   (math-build-units-table)
  282. X   (let ((unit (assq uname math-units-table)))
  283. X     (or unit
  284. X     (error "Unit name \"%s\" not found" uname))
  285. X     (let ((msg (nth 2 unit)))
  286. X       (if (stringp msg)
  287. X       (if (string-match "^\\*" msg)
  288. X           (setq msg (substring msg 1)))
  289. X     (setq msg (symbol-name uname)))
  290. X       (if (nth 1 unit)
  291. X       (progn
  292. X         (calc-enter-result 0 "ugdf" (nth 1 unit))
  293. X         (message "Derived unit: %s" msg))
  294. X     (calc-enter-result 0 "ugdf" (list 'var uname
  295. X                       (intern
  296. X                        (concat "var-"
  297. X                            (symbol-name uname)))))
  298. X     (message "Base unit: %s" msg)))))
  299. )
  300. X
  301. (defun calc-permanent-units ()
  302. X  (interactive)
  303. X  (calc-wrapper
  304. X   (let (pos)
  305. X     (set-buffer (find-file-noselect (substitute-in-file-name
  306. X                      calc-settings-file)))
  307. X     (goto-char (point-min))
  308. X     (if (and (search-forward ";;; Custom units stored by Calc" nil t)
  309. X          (progn
  310. X        (beginning-of-line)
  311. X        (setq pos (point))
  312. X        (search-forward "\n;;; End of custom units" nil t)))
  313. X     (progn
  314. X       (beginning-of-line)
  315. X       (forward-line 1)
  316. X       (delete-region pos (point)))
  317. X       (goto-char (point-max))
  318. X       (insert "\n\n")
  319. X       (forward-char -1))
  320. X     (insert ";;; Custom units stored by Calc on " (current-time-string) "\n")
  321. X     (if math-additional-units
  322. X     (progn
  323. X       (insert "(setq math-additional-units '(\n")
  324. X       (let ((list math-additional-units))
  325. X         (while list
  326. X           (insert "  (" (symbol-name (car (car list))) " "
  327. X               (if (nth 1 (car list))
  328. X               (if (stringp (nth 1 (car list)))
  329. X                   (prin1-to-string (nth 1 (car list)))
  330. X                 (prin1-to-string (math-format-flat-expr
  331. X                           (nth 1 (car list)) 0)))
  332. X             "nil")
  333. X               " "
  334. X               (prin1-to-string (nth 2 (car list)))
  335. X               ")\n")
  336. X           (setq list (cdr list))))
  337. X       (insert "))\n"))
  338. X       (insert ";;; (no custom units defined)\n"))
  339. X     (insert ";;; End of custom units\n")
  340. X     (save-buffer)))
  341. )
  342. X
  343. X
  344. X
  345. X
  346. X
  347. ;;; Units operations.
  348. X
  349. ;;; Units table last updated 9-Jan-91 by Ulrich Mueller (ulm@vsnhd1.cern.ch)
  350. ;;; with some additions by Przemek Klosowski (przemek@rrdstrad.nist.gov)
  351. X
  352. (defvar math-standard-units
  353. X  '( ;; Length
  354. X     ( m       nil             "*Meter" )
  355. X     ( in      "2.54 cm"             "Inch" )
  356. X     ( ft      "12 in"             "Foot" )
  357. X     ( yd      "3 ft"             "Yard" )
  358. X     ( mi      "5280 ft"         "Mile" )
  359. X     ( au      "1.495979e11 m"       "Astronomical Unit" )
  360. X     ( lyr     "9460536207068016 m"  "Light Year" )
  361. X     ( pc      "206264.80625 au"     "Parsec" )
  362. X     ( nmi     "1852 m"             "Nautical Mile" )
  363. X     ( fath    "6 ft"             "Fathom" )
  364. X     ( u       "1 um"             "Micron" )
  365. X     ( mil     "in/1000"         "Mil" )
  366. X     ( point   "in/72"             "Point (1/72 inch)" )
  367. X     ( tpt     "in/72.27"         "Point (TeX conventions)" )
  368. X     ( Ang     "1e-10 m"         "Angstrom" )
  369. X     ( mfi     "mi+ft+in"         "Miles + feet + inches" )
  370. X     
  371. X     ;; Area
  372. X     ( hect    "10000 m^2"         "*Hectare" )
  373. X     ( acre    "mi^2 / 640"         "Acre" )
  374. X     ( b       "1e-28 m^2"         "Barn" )
  375. X     
  376. X     ;; Volume
  377. X     ( l       "1e-3 m^3"         "*Liter" )
  378. X     ( L       "1e-3 m^3"         "Liter" )
  379. X     ( gal     "4 qt"             "US Gallon" )
  380. X     ( qt      "2 pt"             "Quart" )
  381. X     ( pt      "2 cup"             "Pint" )
  382. X     ( cup     "8 ozfl"             "Cup" )
  383. X     ( ozfl    "2 tbsp"             "Fluid Ounce" )
  384. X     ( floz    "2 tbsp"             "Fluid Ounce" )
  385. X     ( tbsp    "3 tsp"             "Tablespoon" )
  386. X     ( tsp     "4.92892159375 ml"    "Teaspoon" )
  387. X     ( vol     "tsp+tbsp+ozfl+cup+pt+qt+gal" "Gallons + ... + teaspoons" )
  388. X     ( galC    "4.54609 l"         "Canadian Gallon" )
  389. X     ( galUK   "4.546092 l"         "UK Gallon" )
  390. X     
  391. X     ;; Time
  392. X     ( s       nil             "*Second" )
  393. X     ( sec     "s"             "Second" )
  394. X     ( min     "60 s"             "Minute" )
  395. X     ( hr      "60 min"             "Hour" )
  396. X     ( day     "24 hr"             "Day" )
  397. X     ( wk      "7 day"             "Week" )
  398. X     ( hms     "wk+day+hr+min+s"     "Hours, minutes, seconds" )
  399. X     ( yr      "365.25 day"         "Year" )
  400. X     ( Hz      "1/s"             "Hertz" )
  401. X
  402. X     ;; Speed
  403. X     ( mph     "mi/hr"             "*Miles per hour" )
  404. X     ( kph     "km/hr"             "Kilometers per hour" )
  405. X     ( knot    "nmi/hr"             "Knot" )
  406. X     ( c       "2.99792458e8 m/s"    "Speed of light" )     
  407. X     
  408. X     ;; Acceleration
  409. X     ( ga      "9.80665 m/s^2"         "*\"g\" acceleration" )
  410. X
  411. X     ;; Mass
  412. X     ( g       nil                   "*Gram" )
  413. X     ( lb      "16 oz"             "Pound (mass)" )
  414. X     ( oz      "28.349523125 g"         "Ounce (mass)" )
  415. X     ( ton     "2000 lb"         "Ton" )
  416. X     ( tpo     "ton+lb+oz"         "Tons + pounds + ounces (mass)" )
  417. X     ( t       "1000 kg"         "Metric ton" )
  418. X     ( tonUK   "1016.0469088 kg"     "UK ton" )
  419. X     ( lbt     "12 ozt"             "Troy pound" )
  420. X     ( ozt     "31.103475 g"         "Troy ounce" )
  421. X     ( ct      ".2 g"             "Carat" )
  422. X     ( amu     "1.6605402e-24 g"     "Unified atomic mass" )
  423. X
  424. X     ;; Force
  425. X     ( N       "m kg/s^2"         "*Newton" )
  426. X     ( dyn     "1e-5 N"             "Dyne" )
  427. X     ( gf      "ga g"             "Gram (force)" )
  428. X     ( lbf     "4.44822161526 N"     "Pound (force)" )
  429. X     ( kip     "1000 lbf"         "Kilopound (force)" )
  430. X     ( pdl     "0.138255 N"         "Poundal" )
  431. X
  432. X     ;; Energy
  433. X     ( J       "N m"             "*Joule" )
  434. X     ( erg     "1e-7 J"             "Erg" )
  435. X     ( cal     "4.1868 J"         "International Table Calorie" )
  436. X     ( Btu     "1055.05585262 J"     "International Table Btu" )
  437. X     ( eV      "ech V"               "Electron volt" )
  438. X     ( ev      "eV"                  "Electron volt" )
  439. X     ( therm   "105506000 J"         "EEC therm" )
  440. X     ( invcm   "h c/cm"               "Energy in inverse centimeters" )
  441. X     ( Kayser  "invcm"             "Kayser (inverse centimeter energy)" )
  442. X     ( men     "100/invcm"         "Inverse energy in meters" )
  443. X     ( Hzen    "h Hz"             "Energy in Hertz")
  444. X     ( Ken     "k K"             "Energy in Kelvins")
  445. X     ;; ( invcm   "eV / 8065.47835185"    "Energy in inverse centimeters" )
  446. X     ;; ( Hzen    "eV / 2.41796958004e14" "Energy in Hertz")
  447. X     ;; ( Ken     "eV / 11604.7967327"    "Energy in Kelvins")
  448. X
  449. X     ;; Power
  450. X     ( W       "J/s"             "*Watt" )
  451. X     ( hp      "745.7 W"         "Horsepower" )
  452. X
  453. X     ;; Temperature
  454. X     ( K       nil                   "*Degree Kelvin"     K )
  455. X     ( dK      "K"             "Degree Kelvin"      K )
  456. X     ( degK    "K"             "Degree Kelvin"      K )
  457. X     ( dC      "K"             "Degree Celsius"      C )
  458. X     ( degC    "K"               "Degree Celsius"      C )
  459. X     ( dF      "(5/9) K"         "Degree Fahrenheit"  F )
  460. X     ( degF    "(5/9) K"         "Degree Fahrenheit"  F )
  461. X
  462. X     ;; Pressure
  463. X     ( Pa      "N/m^2"             "*Pascal" )
  464. X     ( bar     "1e5 Pa"             "Bar" )
  465. X     ( atm     "101325 Pa"         "Standard atmosphere" )
  466. X     ( torr    "atm/760"         "Torr" )
  467. X     ( mHg     "1000 torr"         "Meter of mercury" )
  468. X     ( inHg    "25.4 mmHg"         "Inch of mercury" )
  469. X     ( inH2O   "248.84 Pa"         "Inch of water" )
  470. X     ( psi     "6894.75729317 Pa"    "Pound per square inch" )
  471. X
  472. X     ;; Viscosity
  473. X     ( P       "0.1 Pa s"         "*Poise" )
  474. X     ( St      "1e-4 m^2/s"         "Stokes" )
  475. X
  476. X     ;; Electromagnetism
  477. X     ( A       nil                   "*Ampere" )
  478. X     ( C       "A s"             "Coulomb" )
  479. X     ( Fdy     "ech Nav"           "Faraday" )
  480. X     ( e       "1.60217733e-19 C"    "Elementary charge" )
  481. X     ( ech     "1.60217733e-19 C"    "Elementary charge" )
  482. X     ( V       "W/A"             "Volt" )
  483. X     ( ohm     "V/A"             "Ohm" )
  484. X     ( mho     "A/V"             "Mho" )
  485. X     ( S       "A/V"             "Siemens" )
  486. X     ( F       "C/V"             "Farad" )
  487. X     ( H       "Wb/A"             "Henry" )
  488. X     ( T       "Wb/m^2"             "Tesla" )
  489. X     ( G       "1e-4 T"             "Gauss" )
  490. X     ( Wb      "V s"             "Weber" )
  491. X
  492. X     ;; Luminous intensity
  493. X     ( cd      nil                   "*Candela" )
  494. X     ( sb      "1e4 cd/m^2"         "Stilb" )
  495. X     ( lm      "cd sr"             "Lumen" )
  496. X     ( lx      "lm/m^2"             "Lux" )
  497. X     ( ph      "1e4 lx"             "Phot" )
  498. X     ( fc      "10.76 lx"         "Footcandle" )
  499. X     ( lam     "1e4 lm/m^2"         "Lambert" )
  500. X     ( flam    "1.07639104e-3 lam"   "Footlambert" )
  501. X
  502. X     ;; Radioactivity
  503. X     ( Bq      "1/s"               "*Becquerel" )
  504. X     ( Ci      "3.7e10 Bq"         "Curie" )
  505. X     ( Gy      "J/kg"             "Gray" )
  506. X     ( Sv      "Gy"             "Sievert" )
  507. X     ( R       "2.58e-4 C/kg"         "Roentgen" )
  508. X     ( rd      ".01 Gy"             "Rad" )
  509. X     ( rem     "rd"             "Rem" )
  510. X
  511. X     ;; Amount of substance
  512. X     ( mol     nil                   "*Mole" )
  513. X
  514. X     ;; Plane angle
  515. X     ( rad     nil                   "*Radian" )
  516. X     ( circ    "2 pi rad"         "Full circle" )
  517. X     ( rev     "circ"             "Full revolution" )
  518. X     ( deg     "circ/360"            "Degree" )
  519. X     ( arcmin  "deg/60"             "Arc minute" )
  520. X     ( arcsec  "arcmin/60"         "Arc second" )
  521. X     ( grad    "circ/400"            "Grade" )
  522. X     ( rpm     "rev/min"         "Revolutions per minute" )
  523. X
  524. X     ;; Solid angle
  525. X     ( sr      nil             "*Steradian" )
  526. X
  527. X     ;; Other physical quantities (Physics Letters B239, 1 (1990))
  528. X     ( h       "6.6260755e-34 J s"   "*Planck's constant" )
  529. X     ( hbar    "h / 2 pi"         "Planck's constant" )
  530. X     ( mu0     "4 pi 1e-7 H/m"       "Permeability of vacuum" )
  531. X     ( Grav    "6.67259e-11 N m^2/kg^2"  "Gravitational constant" )
  532. X     ( Nav     "6.0221367e23 / mol"  "Avagadro's constant" )
  533. X     ( me      "0.51099906 MeV/c^2"  "Electron rest mass" )
  534. X     ( mp      "1.007276470 amu"     "Proton rest mass" )
  535. X     ( mn      "1.008664904 amu"     "Neutron rest mass" )
  536. X     ( mu      "0.113428913 amu"     "Muon rest mass" )
  537. X     ( Ryd     "1.0973731571e5 invcm" "Rydberg's constant" )
  538. X     ( k       "1.3806513e-23 J/K"   "Boltzmann's constant" )
  539. X     ( fsc     "1 / 137.0359895"     "Fine structure constant" )
  540. X     ( muB     "5.78838263e-11 MeV/T"  "Bohr magneton" )
  541. X     ( muN     "3.15245166e-14 MeV/T"  "Nuclear magneton" )
  542. X     ( mue     "1.001159652193 muB"  "Electron magnetic moment" )
  543. X     ( mup     "2.792847386 muN"     "Proton magnetic moment" )
  544. X     ( R0      "Nav k"               "Molar gas constant" )
  545. X     ( V0      "22.413992 L/mol"     "Standard volume of ideal gas" )
  546. ))
  547. X
  548. X
  549. (defvar math-additional-units nil
  550. X  "*Additional units table for user-defined units.
  551. Must be formatted like math-standard-units.
  552. If this is changed, be sure to set math-units-table to nil to ensure
  553. that the combined units table will be rebuilt.")
  554. X
  555. (defvar math-unit-prefixes
  556. X  '( ( ?E  (float 1 18)  "Exa"    )
  557. X     ( ?P  (float 1 15)  "Peta"   )
  558. X     ( ?T  (float 1 12)  "Tera"      )
  559. X     ( ?G  (float 1 9)   "Giga"      )
  560. X     ( ?M  (float 1 6)   "Mega"      )
  561. X     ( ?k  (float 1 3)   "Kilo"      )
  562. X     ( ?K  (float 1 3)   "Kilo"      )
  563. X     ( ?h  (float 1 2)   "Hecto"  )
  564. X     ( ?H  (float 1 2)   "Hecto"  )
  565. X     ( ?D  (float 1 1)   "Deka"      )
  566. X     ( 0   (float 1 0)   nil      )
  567. X     ( ?d  (float 1 -1)  "Deci"      )
  568. X     ( ?c  (float 1 -2)  "Centi"  )
  569. X     ( ?m  (float 1 -3)  "Milli"  )
  570. X     ( ?u  (float 1 -6)  "Micro"  )
  571. X     ( ?n  (float 1 -9)  "Nano"      )
  572. X     ( ?p  (float 1 -12) "Pico"      )
  573. X     ( ?f  (float 1 -15) "Femto"  )
  574. X     ( ?a  (float 1 -18) "Atto"   )
  575. ))
  576. X
  577. (defvar math-standard-units-systems
  578. X  '( ( base  nil )
  579. X     ( si    ( ( g   '(* (var kg var-kg) (float 1 -3)) ) ) )
  580. X     ( mks   ( ( g   '(* (var kg var-kg) (float 1 -3)) ) ) )
  581. X     ( cgs   ( ( m   '(* (var cm var-cm) 100         ) ) ) )
  582. ))
  583. X
  584. (defvar math-units-table nil
  585. X  "Internal units table derived from math-defined-units.
  586. Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
  587. X
  588. (defvar math-units-table-buffer-valid nil)
  589. X
  590. X
  591. (defun math-build-units-table ()
  592. X  (or math-units-table
  593. X      (let* ((combined-units (append math-additional-units
  594. X                     math-standard-units))
  595. X         (unit-list (mapcar 'car combined-units))
  596. X         tab)
  597. X    (message "Building units table...")
  598. X    (setq math-units-table-buffer-valid nil)
  599. X    (setq tab (mapcar (function
  600. X               (lambda (x)
  601. X                 (list (car x)
  602. X                   (and (nth 1 x)
  603. X                    (if (stringp (nth 1 x))
  604. X                        (let ((exp (math-read-plain-expr
  605. X                            (nth 1 x))))
  606. X                          (if (eq (car-safe exp) 'error)
  607. X                          (error "Format error in definition of %s in units table: %s"
  608. X                             (car x) (nth 2 exp))
  609. X                        exp))
  610. X                      (nth 1 x)))
  611. X                   (nth 2 x)
  612. X                   (nth 3 x)
  613. X                   (and (not (nth 1 x))
  614. X                    (list (cons (car x) 1))))))
  615. X              combined-units))
  616. X    (let ((math-units-table tab))
  617. X      (mapcar 'math-find-base-units tab))
  618. X    (message "Building units table...done")
  619. X    (setq math-units-table tab)))
  620. )
  621. X
  622. (defun math-find-base-units (entry)
  623. X  (if (eq (nth 4 entry) 'boom)
  624. X      (error "Circular definition involving unit %s" (car entry)))
  625. X  (or (nth 4 entry)
  626. X      (let (base)
  627. X    (setcar (nthcdr 4 entry) 'boom)
  628. X    (math-find-base-units-rec (nth 1 entry) 1)
  629. X    '(or base
  630. X        (error "Dimensionless definition for unit %s" (car entry)))
  631. X    (while (eq (cdr (car base)) 0)
  632. X      (setq base (cdr base)))
  633. X    (let ((b base))
  634. X      (while (cdr b)
  635. X        (if (eq (cdr (car (cdr b))) 0)
  636. X        (setcdr b (cdr (cdr b)))
  637. X          (setq b (cdr b)))))
  638. X    (setq base (sort base 'math-compare-unit-names))
  639. X    (setcar (nthcdr 4 entry) base)
  640. X    base))
  641. )
  642. X
  643. (defun math-compare-unit-names (a b)
  644. X  (memq (car b) (cdr (memq (car a) unit-list)))
  645. )
  646. X
  647. (defun math-find-base-units-rec (expr pow)
  648. X  (let ((u (math-check-unit-name expr)))
  649. X    (cond (u
  650. X       (let ((ulist (math-find-base-units u)))
  651. X         (while ulist
  652. X           (let ((p (* (cdr (car ulist)) pow))
  653. X             (old (assq (car (car ulist)) base)))
  654. X         (if old
  655. X             (setcdr old (+ (cdr old) p))
  656. X           (setq base (cons (cons (car (car ulist)) p) base))))
  657. X           (setq ulist (cdr ulist)))))
  658. X      ((math-scalarp expr))
  659. X      ((and (eq (car expr) '^)
  660. X        (integerp (nth 2 expr)))
  661. X       (math-find-base-units-rec (nth 1 expr) (* pow (nth 2 expr))))
  662. X      ((eq (car expr) '*)
  663. X       (math-find-base-units-rec (nth 1 expr) pow)
  664. X       (math-find-base-units-rec (nth 2 expr) pow))
  665. X      ((eq (car expr) '/)
  666. X       (math-find-base-units-rec (nth 1 expr) pow)
  667. X       (math-find-base-units-rec (nth 2 expr) (- pow)))
  668. X      ((eq (car expr) 'neg)
  669. X       (math-find-base-units-rec (nth 1 expr) pow))
  670. X      ((eq (car expr) '+)
  671. X       (math-find-base-units-rec (nth 1 expr) pow))
  672. X      ((eq (car expr) 'var)
  673. X       (or (eq (nth 1 expr) 'pi)
  674. X           (error "Unknown name %s in defining expression for unit %s"
  675. X              (nth 1 expr) (car entry))))
  676. X      (t (error "Malformed defining expression for unit %s" (car entry)))))
  677. )
  678. X
  679. X
  680. (defun math-units-in-expr-p (expr sub-exprs)
  681. X  (and (consp expr)
  682. X       (if (eq (car expr) 'var)
  683. X       (math-check-unit-name expr)
  684. X     (and (or sub-exprs
  685. X          (memq (car expr) '(* / ^)))
  686. X          (or (math-units-in-expr-p (nth 1 expr) sub-exprs)
  687. X          (math-units-in-expr-p (nth 2 expr) sub-exprs)))))
  688. )
  689. X
  690. (defun math-only-units-in-expr-p (expr)
  691. X  (and (consp expr)
  692. X       (if (eq (car expr) 'var)
  693. X       (math-check-unit-name expr)
  694. X     (if (memq (car expr) '(* /))
  695. X         (and (math-only-units-in-expr-p (nth 1 expr))
  696. X          (math-only-units-in-expr-p (nth 2 expr)))
  697. X       (and (eq (car expr) '^)
  698. X        (and (math-only-units-in-expr-p (nth 1 expr))
  699. X             (math-realp (nth 2 expr)))))))
  700. )
  701. X
  702. (defun math-single-units-in-expr-p (expr)
  703. X  (cond ((math-scalarp expr) nil)
  704. X    ((eq (car expr) 'var)
  705. X     (math-check-unit-name expr))
  706. X    ((eq (car expr) '*)
  707. X     (let ((u1 (math-single-units-in-expr-p (nth 1 expr)))
  708. X           (u2 (math-single-units-in-expr-p (nth 2 expr))))
  709. X       (or (and u1 u2 'wrong)
  710. X           u1
  711. X           u2)))
  712. X    ((eq (car expr) '/)
  713. X     (if (math-units-in-expr-p (nth 2 expr))
  714. X         'wrong
  715. X       (math-single-units-in-expr-p (nth 1 expr))))
  716. X    (t 'wrong))
  717. )
  718. X
  719. (defun math-check-unit-name (v)
  720. X  (and (eq (car-safe v) 'var)
  721. X       (or (assq (nth 1 v) (or math-units-table (math-build-units-table)))
  722. X       (let ((name (symbol-name (nth 1 v))))
  723. X         (and (> (length name) 1)
  724. X          (assq (aref name 0) math-unit-prefixes)
  725. X          (or (assq (intern (substring name 1)) math-units-table)
  726. X              (and (eq (aref name 0) ?M)
  727. X               (> (length name) 3)
  728. X               (eq (aref name 1) ?e)
  729. X               (eq (aref name 2) ?g)
  730. X               (assq (intern (substring name 3))
  731. X                 math-units-table)))))))
  732. )
  733. X
  734. X
  735. (defun math-to-standard-units (expr which-standard)
  736. X  (math-to-standard-rec expr)
  737. )
  738. X
  739. (defun math-to-standard-rec (expr)
  740. X  (if (eq (car-safe expr) 'var)
  741. X      (let ((u (math-check-unit-name expr))
  742. X        (base (nth 1 expr)))
  743. X    (if u
  744. X        (progn
  745. X          (if (nth 1 u)
  746. X          (setq expr (math-to-standard-rec (nth 1 u)))
  747. X        (let ((st (assq (car u) which-standard)))
  748. X          (if st
  749. X              (setq expr (nth 1 st))
  750. X            (setq expr (list 'var (car u)
  751. X                     (intern (concat "var-"
  752. X                             (symbol-name
  753. X                              (car u)))))))))
  754. X          (or (null u)
  755. X          (eq base (car u))
  756. X          (setq expr (list '*
  757. X                   (nth 1 (assq (aref (symbol-name base) 0)
  758. X                        math-unit-prefixes))
  759. X                   expr)))
  760. X          expr)
  761. X      (if (eq base 'pi)
  762. X          (math-pi)
  763. X        expr)))
  764. X    (if (Math-primp expr)
  765. X    expr
  766. X      (cons (car expr)
  767. X        (mapcar 'math-to-standard-rec (cdr expr)))))
  768. )
  769. X
  770. (defun math-apply-units (expr units ulist &optional pure)
  771. X  (if ulist
  772. X      (let ((new 0)
  773. X        value)
  774. X    (setq expr (math-simplify-units expr))
  775. X    (or (math-numberp expr)
  776. X        (error "Incompatible units"))
  777. X    (while (cdr ulist)
  778. X      (setq value (math-div expr (nth 1 (car ulist)))
  779. X        value (math-floor (let ((calc-internal-prec
  780. X                     (1- calc-internal-prec)))
  781. X                    (math-normalize value)))
  782. X        new (math-add new (math-mul value (car (car ulist))))
  783. X        expr (math-sub expr (math-mul value (nth 1 (car ulist))))
  784. X        ulist (cdr ulist)))
  785. X    (math-add new (math-mul (math-div expr (nth 1 (car ulist)))
  786. X                (car (car ulist)))))
  787. X    (math-simplify-units (if pure
  788. X                 expr
  789. X               (list '* expr units))))
  790. )
  791. X
  792. (defun math-decompose-units (units)
  793. X  (let ((u (math-check-unit-name units)))
  794. X    (and u (eq (car-safe (nth 1 u)) '+)
  795. X     (setq units (nth 1 u))))
  796. X  (setq units (calcFunc-expand units))
  797. X  (and (eq (car-safe units) '+)
  798. X       (let ((entry (list units calc-internal-prec calc-prefer-frac)))
  799. X     (or (equal entry (car math-decompose-units-cache))
  800. X         (let ((ulist nil)
  801. X           (utemp units)
  802. X           qty unit)
  803. X           (while (eq (car-safe utemp) '+)
  804. X         (setq ulist (cons (math-decompose-unit-part (nth 2 utemp))
  805. X                   ulist)
  806. X               utemp (nth 1 utemp)))
  807. X           (setq ulist (cons (math-decompose-unit-part utemp) ulist)
  808. X             utemp ulist)
  809. X           (while (setq utemp (cdr utemp))
  810. X         (or (equal (nth 2 (car utemp)) (nth 2 (car ulist)))
  811. X             (error "Inconsistent units in sum")))
  812. X           (setq math-decompose-units-cache
  813. X             (cons entry
  814. X               (sort ulist
  815. X                 (function
  816. X                  (lambda (x y)
  817. X                    (not (Math-lessp (nth 1 x)
  818. X                             (nth 1 y))))))))))
  819. X     (cdr math-decompose-units-cache)))
  820. )
  821. (setq math-decompose-units-cache nil)
  822. X
  823. (defun math-decompose-unit-part (unit)
  824. X  (cons unit
  825. X    (math-is-multiple (math-simplify-units (math-to-standard-units
  826. X                        unit nil))
  827. X              t))
  828. )
  829. X
  830. (defun math-find-compatible-unit (expr unit)
  831. X  (let ((u (math-check-unit-name unit)))
  832. X    (if u
  833. X    (math-find-compatible-unit-rec expr 1)))
  834. )
  835. X
  836. (defun math-find-compatible-unit-rec (expr pow)
  837. X  (cond ((eq (car-safe expr) '*)
  838. X     (or (math-find-compatible-unit-rec (nth 1 expr) pow)
  839. X         (math-find-compatible-unit-rec (nth 2 expr) pow)))
  840. X    ((eq (car-safe expr) '/)
  841. X     (or (math-find-compatible-unit-rec (nth 1 expr) pow)
  842. X         (math-find-compatible-unit-rec (nth 2 expr) (- pow))))
  843. X    ((and (eq (car-safe expr) '^)
  844. X          (integerp (nth 2 expr)))
  845. X     (math-find-compatible-unit-rec (nth 1 expr) (* pow (nth 2 expr))))
  846. X    (t
  847. X     (let ((u2 (math-check-unit-name expr)))
  848. X       (if (equal (nth 4 u) (nth 4 u2))
  849. X           (cons expr pow)))))
  850. )
  851. X
  852. (defun math-convert-units (expr new-units &optional pure)
  853. X  (math-with-extra-prec 2
  854. X    (let ((compat (and (not pure) (math-find-compatible-unit expr new-units)))
  855. X      (unit-list nil)
  856. X      (math-combining-units nil))
  857. X      (if compat
  858. X      (math-simplify-units
  859. X       (math-mul (math-mul (math-simplify-units
  860. X                (math-div expr (math-pow (car compat)
  861. X                             (cdr compat))))
  862. X                   (math-pow new-units (cdr compat)))
  863. X             (math-simplify-units
  864. X              (math-to-standard-units
  865. X               (math-pow (math-div (car compat) new-units)
  866. X                 (cdr compat))
  867. X               nil))))
  868. X    (if (setq unit-list (math-decompose-units new-units))
  869. X        (setq new-units (nth 2 (car unit-list))))
  870. X    (if (eq (car-safe expr) '+)
  871. X        (setq expr (math-simplify-units expr)))
  872. X    (if (math-units-in-expr-p expr t)
  873. X        (math-convert-units-rec expr)
  874. X      (math-apply-units (math-to-standard-units
  875. X                 (list '/ expr new-units) nil)
  876. X                new-units unit-list pure)))))
  877. )
  878. X
  879. (defun math-convert-units-rec (expr)
  880. X  (if (math-units-in-expr-p expr nil)
  881. X      (math-apply-units (math-to-standard-units (list '/ expr new-units) nil)
  882. X            new-units unit-list pure)
  883. X    (if (Math-primp expr)
  884. X    expr
  885. X      (cons (car expr)
  886. X        (mapcar 'math-convert-units-rec (cdr expr)))))
  887. )
  888. X
  889. (defun math-convert-temperature (expr old new &optional pure)
  890. X  (let* ((units (math-single-units-in-expr-p expr))
  891. X     (uold (if old
  892. X           (if (or (null units)
  893. X               (equal (nth 1 old) (car units)))
  894. X               (math-check-unit-name old)
  895. X             (error "Inconsistent temperature units"))
  896. X         units))
  897. X     (unew (math-check-unit-name new)))
  898. X    (or (and (consp unew) (nth 3 unew))
  899. X    (error "Not a valid temperature unit"))
  900. X    (or (and (consp uold) (nth 3 uold))
  901. X    (error "Not a pure temperature expression"))
  902. X    (let ((v (car uold)))
  903. X      (setq expr (list '/ expr (list 'var v
  904. X                     (intern (concat "var-"
  905. X                             (symbol-name v)))))))
  906. X    (or (eq (nth 3 uold) (nth 3 unew))
  907. X    (cond ((eq (nth 3 uold) 'K)
  908. X           (setq expr (list '- expr '(float 27315 -2)))
  909. X           (if (eq (nth 3 unew) 'F)
  910. X           (setq expr (list '+ (list '* expr '(frac 9 5)) 32))))
  911. X          ((eq (nth 3 uold) 'C)
  912. X           (if (eq (nth 3 unew) 'F)
  913. X           (setq expr (list '+ (list '* expr '(frac 9 5)) 32))
  914. X         (setq expr (list '+ expr '(float 27315 -2)))))
  915. X          (t
  916. X           (setq expr (list '* (list '- expr 32) '(frac 5 9)))
  917. X           (if (eq (nth 3 unew) 'K)
  918. X           (setq expr (list '+ expr '(float 27315 -2)))))))
  919. X    (if pure
  920. X    expr
  921. X      (list '* expr new)))
  922. )
  923. X
  924. X
  925. X
  926. (defun math-simplify-units (a)
  927. X  (let ((math-simplifying-units t)
  928. X    (calc-matrix-mode 'scalar))
  929. X    (math-simplify a))
  930. )
  931. (fset 'calcFunc-usimplify (symbol-function 'math-simplify-units))
  932. X
  933. (math-defsimplify (+ -)
  934. X  (and math-simplifying-units
  935. X       (math-units-in-expr-p (nth 1 expr) nil)
  936. X       (let* ((units (math-extract-units (nth 1 expr)))
  937. X          (ratio (math-simplify (math-to-standard-units
  938. X                     (list '/ (nth 2 expr) units) nil))))
  939. X     (if (math-units-in-expr-p ratio nil)
  940. X         (progn
  941. X           (calc-record-why "*Inconsistent units" expr)
  942. X           expr)
  943. X       (list '* (math-add (math-remove-units (nth 1 expr))
  944. X                  (if (eq (car expr) '-) (math-neg ratio) ratio))
  945. X         units))))
  946. )
  947. X
  948. (math-defsimplify *
  949. X  (math-simplify-units-prod)
  950. )
  951. X
  952. (defun math-simplify-units-prod ()
  953. X  (and math-simplifying-units
  954. X       calc-autorange-units
  955. X       (Math-realp (nth 1 expr))
  956. X       (let* ((num (math-float (nth 1 expr)))
  957. X          (xpon (calcFunc-xpon num))
  958. X          (unitp (cdr (cdr expr)))
  959. X          (unit (car unitp))
  960. X          (pow (if (eq (car expr) '*) 1 -1))
  961. X          u)
  962. X     (and (eq (car-safe unit) '*)
  963. X          (setq unitp (cdr unit)
  964. X            unit (car unitp)))
  965. X     (and (eq (car-safe unit) '^)
  966. X          (integerp (nth 2 unit))
  967. X          (setq pow (* pow (nth 2 unit))
  968. X            unitp (cdr unit)
  969. X            unit (car unitp)))
  970. X     (and (setq u (math-check-unit-name unit))
  971. X          (integerp xpon)
  972. X          (or (< xpon 0)
  973. X          (>= xpon (if (eq (car u) 'm) 1 3)))
  974. X          (let* ((uxpon 0)
  975. X             (pref (if (< pow 0)
  976. X                   (reverse math-unit-prefixes)
  977. X                 math-unit-prefixes))
  978. X             (p pref)
  979. X             pxpon pname)
  980. X        (or (eq (car u) (nth 1 unit))
  981. X            (setq uxpon (* pow
  982. X                   (nth 2 (nth 1 (assq
  983. X                          (aref (symbol-name
  984. X                             (nth 1 unit)) 0)
  985. X                          math-unit-prefixes))))))
  986. X        (setq xpon (+ xpon uxpon))
  987. X        (while (and p
  988. X                (or (memq (car (car p)) '(?d ?D ?h ?H))
  989. X                (and (eq (car (car p)) ?c)
  990. X                     (not (eq (car u) 'm)))
  991. X                (< xpon (setq pxpon (* (nth 2 (nth 1 (car p)))
  992. X                               pow)))
  993. X                (progn
  994. X                  (setq pname (math-build-var-name
  995. X                           (if (eq (car (car p)) 0)
  996. X                           (car u)
  997. X                         (concat (char-to-string
  998. X                              (car (car p)))
  999. X                             (symbol-name
  1000. X                              (car u))))))
  1001. X                  (and (/= (car (car p)) 0)
  1002. X                       (assq (nth 1 pname)
  1003. X                         math-units-table)))))
  1004. X          (setq p (cdr p)))
  1005. X        (and p
  1006. X             (/= pxpon uxpon)
  1007. X             (or (not (eq p pref))
  1008. X             (< xpon (+ pxpon (* (math-abs pow) 3))))
  1009. X             (progn
  1010. X               (setcar (cdr expr)
  1011. X                   (let ((calc-prefer-frac nil))
  1012. X                 (calcFunc-scf (nth 1 expr)
  1013. X                           (- uxpon pxpon))))
  1014. X               (setcar unitp pname)
  1015. X               expr))))))
  1016. )
  1017. X
  1018. (math-defsimplify /
  1019. X  (and math-simplifying-units
  1020. X       (let ((np (cdr expr))
  1021. X         n nn)
  1022. X     (setq n (if (eq (car-safe (nth 2 expr)) '*)
  1023. X             (cdr (nth 2 expr))
  1024. X           (nthcdr 2 expr)))
  1025. X     (if (math-realp (car n))
  1026. X         (progn
  1027. X           (setcar (cdr expr) (math-mul (nth 1 expr)
  1028. X                        (let ((calc-prefer-frac nil))
  1029. X                          (math-div 1 (car n)))))
  1030. X           (setcar n 1)))
  1031. X     (while (eq (car-safe (setq n (car np))) '*)
  1032. X       (math-simplify-units-divisor (cdr n) (cdr (cdr expr)))
  1033. X       (setq np (cdr (cdr n))))
  1034. X     (math-simplify-units-divisor np (cdr (cdr expr)))
  1035. X     (math-simplify-units-prod)
  1036. X     expr))
  1037. )
  1038. X
  1039. (defun math-simplify-units-divisor (np dp)
  1040. X  (let ((n (car np))
  1041. X    d dd temp)
  1042. X    (while (eq (car-safe (setq d (car dp))) '*)
  1043. X      (if (setq temp (math-simplify-units-quotient n (nth 1 d)))
  1044. X      (progn
  1045. X        (setcar np (setq n temp))
  1046. X        (setcar (cdr d) 1)))
  1047. X      (setq dp (cdr (cdr d))))
  1048. X    (if (setq temp (math-simplify-units-quotient n d))
  1049. X    (progn
  1050. X      (setcar np (setq n temp))
  1051. X      (setcar dp 1))))
  1052. )
  1053. X
  1054. ;; Simplify, e.g., "in / cm" to "2.54" in a units expression.
  1055. (defun math-simplify-units-quotient (n d)
  1056. X  (let ((un (math-check-unit-name n))
  1057. X    (ud (math-check-unit-name d)))
  1058. X    (and un ud
  1059. X     (equal (nth 4 un) (nth 4 ud))
  1060. X     (math-to-standard-units (list '/ n d) nil)))
  1061. )
  1062. X
  1063. (math-defsimplify ^
  1064. X  (and math-simplifying-units
  1065. X       (math-realp (nth 2 expr))
  1066. X       (if (memq (car-safe (nth 1 expr)) '(* /))
  1067. X       (list (car (nth 1 expr))
  1068. X         (list '^ (nth 1 (nth 1 expr)) (nth 2 expr))
  1069. X         (list '^ (nth 2 (nth 1 expr)) (nth 2 expr)))
  1070. X     (math-simplify-units-pow (nth 1 expr) (nth 2 expr))))
  1071. )
  1072. X
  1073. (math-defsimplify calcFunc-sqrt
  1074. X  (and math-simplifying-units
  1075. X       (if (memq (car-safe (nth 1 expr)) '(* /))
  1076. X       (list (car (nth 1 expr))
  1077. X         (list 'calcFunc-sqrt (nth 1 (nth 1 expr)))
  1078. X         (list 'calcFunc-sqrt (nth 2 (nth 1 expr))))
  1079. X     (math-simplify-units-pow (nth 1 expr) '(frac 1 2))))
  1080. )
  1081. X
  1082. (math-defsimplify (calcFunc-floor
  1083. X           calcFunc-ceil
  1084. X           calcFunc-round
  1085. X           calcFunc-rounde
  1086. X           calcFunc-roundu
  1087. X           calcFunc-trunc
  1088. X           calcFunc-float
  1089. X           calcFunc-frac
  1090. X           calcFunc-abs
  1091. X           calcFunc-clean)
  1092. X  (and math-simplifying-units
  1093. X       (= (length expr) 2)
  1094. X       (if (math-only-units-in-expr-p (nth 1 expr))
  1095. X       (nth 1 expr)
  1096. X     (if (and (memq (car-safe (nth 1 expr)) '(* /))
  1097. X          (or (math-only-units-in-expr-p
  1098. X               (nth 1 (nth 1 expr)))
  1099. X              (math-only-units-in-expr-p
  1100. X               (nth 2 (nth 1 expr)))))
  1101. X         (list (car (nth 1 expr))
  1102. X           (cons (car expr)
  1103. X             (cons (nth 1 (nth 1 expr))
  1104. X                   (cdr (cdr expr))))
  1105. X           (cons (car expr)
  1106. X             (cons (nth 2 (nth 1 expr))
  1107. X                   (cdr (cdr expr)))))))))
  1108. X
  1109. (defun math-simplify-units-pow (a pow)
  1110. X  (if (and (eq (car-safe a) '^)
  1111. X       (math-check-unit-name (nth 1 a))
  1112. X       (math-realp (nth 2 a)))
  1113. X      (list '^ (nth 1 a) (math-mul pow (nth 2 a)))
  1114. X    (let* ((u (math-check-unit-name a))
  1115. X       (pf (math-to-simple-fraction pow))
  1116. X       (d (and (eq (car-safe pf) 'frac) (nth 2 pf))))
  1117. X      (and u d
  1118. X       (math-units-are-multiple u d)
  1119. X       (list '^ (math-to-standard-units a nil) pow))))
  1120. )
  1121. X
  1122. X
  1123. (defun math-units-are-multiple (u n)
  1124. X  (setq u (nth 4 u))
  1125. X  (while (and u (= (% (cdr (car u)) n) 0))
  1126. X    (setq u (cdr u)))
  1127. X  (null u)
  1128. )
  1129. X
  1130. (math-defsimplify calcFunc-sin
  1131. X  (and math-simplifying-units
  1132. X       (math-units-in-expr-p (nth 1 expr) nil)
  1133. X       (let ((rad (math-simplify-units
  1134. X           (math-evaluate-expr
  1135. X            (math-to-standard-units (nth 1 expr) nil))))
  1136. X         (calc-angle-mode 'rad))
  1137. X     (and (eq (car-safe rad) '*)
  1138. X          (math-realp (nth 1 rad))
  1139. X          (eq (car-safe (nth 2 rad)) 'var)
  1140. X          (eq (nth 1 (nth 2 rad)) 'rad)
  1141. X          (list 'calcFunc-sin (nth 1 rad)))))
  1142. )
  1143. X
  1144. (math-defsimplify calcFunc-cos
  1145. X  (and math-simplifying-units
  1146. X       (math-units-in-expr-p (nth 1 expr) nil)
  1147. X       (let ((rad (math-simplify-units
  1148. X           (math-evaluate-expr
  1149. X            (math-to-standard-units (nth 1 expr) nil))))
  1150. X         (calc-angle-mode 'rad))
  1151. X     (and (eq (car-safe rad) '*)
  1152. X          (math-realp (nth 1 rad))
  1153. X          (eq (car-safe (nth 2 rad)) 'var)
  1154. X          (eq (nth 1 (nth 2 rad)) 'rad)
  1155. X          (list 'calcFunc-cos (nth 1 rad)))))
  1156. )
  1157. X
  1158. (math-defsimplify calcFunc-tan
  1159. X  (and math-simplifying-units
  1160. X       (math-units-in-expr-p (nth 1 expr) nil)
  1161. X       (let ((rad (math-simplify-units
  1162. X           (math-evaluate-expr
  1163. X            (math-to-standard-units (nth 1 expr) nil))))
  1164. X         (calc-angle-mode 'rad))
  1165. X     (and (eq (car-safe rad) '*)
  1166. X          (math-realp (nth 1 rad))
  1167. X          (eq (car-safe (nth 2 rad)) 'var)
  1168. X          (eq (nth 1 (nth 2 rad)) 'rad)
  1169. X          (list 'calcFunc-tan (nth 1 rad)))))
  1170. )
  1171. X
  1172. X
  1173. (defun math-remove-units (expr)
  1174. X  (if (math-check-unit-name expr)
  1175. X      1
  1176. X    (if (Math-primp expr)
  1177. X    expr
  1178. X      (cons (car expr)
  1179. X        (mapcar 'math-remove-units (cdr expr)))))
  1180. )
  1181. X
  1182. (defun math-extract-units (expr)
  1183. X  (if (memq (car-safe expr) '(* /))
  1184. X      (cons (car expr)
  1185. X        (mapcar 'math-extract-units (cdr expr)))
  1186. X    (if (math-check-unit-name expr) expr 1))
  1187. )
  1188. X
  1189. (defun math-build-units-table-buffer (enter-buffer)
  1190. X  (if (not (and math-units-table math-units-table-buffer-valid
  1191. X        (get-buffer "*Units Table*")))
  1192. X      (let ((buf (get-buffer-create "*Units Table*"))
  1193. X        (uptr (math-build-units-table))
  1194. X        (calc-language (if (eq calc-language 'big) nil calc-language))
  1195. X        (calc-float-format '(float 0))
  1196. X        (calc-group-digits nil)
  1197. X        (calc-number-radix 10)
  1198. X        (calc-point-char ".")
  1199. X        (std nil)
  1200. X        u name shadowed)
  1201. X    (save-excursion
  1202. X      (message "Formatting units table...")
  1203. X      (set-buffer buf)
  1204. X      (setq buffer-read-only nil)
  1205. X      (erase-buffer)
  1206. X      (insert "Calculator Units Table:\n\n")
  1207. X      (insert "Unit    Type  Definition                  Description\n\n")
  1208. X      (while uptr
  1209. X        (setq u (car uptr)
  1210. X          name (nth 2 u))
  1211. X        (if (eq (car u) 'm)
  1212. X        (setq std t))
  1213. X        (setq shadowed (and std (assq (car u) math-additional-units)))
  1214. X        (if (and name
  1215. X             (> (length name) 1)
  1216. X             (eq (aref name 0) ?\*))
  1217. X        (progn
  1218. X          (or (eq uptr math-units-table)
  1219. X              (insert "\n"))
  1220. X          (setq name (substring name 1))))
  1221. X        (insert " ")
  1222. X        (and shadowed (insert "("))
  1223. X        (insert (symbol-name (car u)))
  1224. X        (and shadowed (insert ")"))
  1225. X        (if (nth 3 u)
  1226. X        (progn
  1227. X          (indent-to 10)
  1228. X          (insert (symbol-name (nth 3 u))))
  1229. X          (or std
  1230. X          (progn
  1231. X            (indent-to 10)
  1232. X            (insert "U"))))
  1233. X        (indent-to 14)
  1234. X        (and shadowed (insert "("))
  1235. X        (if (nth 1 u)
  1236. X        (insert (math-format-value (nth 1 u) 80))
  1237. X          (insert (symbol-name (car u))))
  1238. X        (and shadowed (insert ")"))
  1239. X        (indent-to 41)
  1240. X        (insert " ")
  1241. X        (if name
  1242. X        (insert name))
  1243. X        (if shadowed
  1244. X        (insert " (redefined above)")
  1245. X          (or (nth 1 u)
  1246. X          (insert " (base unit)")))
  1247. X        (insert "\n")
  1248. X        (setq uptr (cdr uptr)))
  1249. X      (insert "\n\nUnit Prefix Table:\n\n")
  1250. X      (setq uptr math-unit-prefixes)
  1251. X      (while uptr
  1252. X        (setq u (car uptr))
  1253. X        (insert " " (char-to-string (car u)))
  1254. X        (if (equal (nth 1 u) (nth 1 (nth 1 uptr)))
  1255. X        (insert " " (char-to-string (car (car (setq uptr (cdr uptr)))))
  1256. X            "   ")
  1257. X          (insert "     "))
  1258. X        (insert "10^" (int-to-string (nth 2 (nth 1 u))))
  1259. X        (indent-to 15)
  1260. X        (insert "   " (nth 2 u) "\n")
  1261. X        (while (eq (car (car (setq uptr (cdr uptr)))) 0)))
  1262. X      (insert "\n")
  1263. X      (setq buffer-read-only t)
  1264. X      (message "Formatting units table...done"))
  1265. X    (setq math-units-table-buffer-valid t)
  1266. X    (let ((oldbuf (current-buffer)))
  1267. X      (set-buffer buf)
  1268. X      (goto-char (point-min))
  1269. X      (set-buffer oldbuf))
  1270. X    (if enter-buffer
  1271. X        (pop-to-buffer buf)
  1272. X      (display-buffer buf)))
  1273. X    (if enter-buffer
  1274. X    (pop-to-buffer (get-buffer "*Units Table*"))
  1275. X      (display-buffer (get-buffer "*Units Table*"))))
  1276. )
  1277. X
  1278. X
  1279. X
  1280. X
  1281. SHAR_EOF
  1282. echo 'File calc-units.el is complete' &&
  1283. chmod 0644 calc-units.el ||
  1284. echo 'restore of calc-units.el failed'
  1285. Wc_c="`wc -c < 'calc-units.el'`"
  1286. test 41220 -eq "$Wc_c" ||
  1287.     echo 'calc-units.el: original size 41220, current size' "$Wc_c"
  1288. rm -f _shar_wnt_.tmp
  1289. fi
  1290. # ============= calc-yank.el ==============
  1291. if test -f 'calc-yank.el' -a X"$1" != X"-c"; then
  1292.     echo 'x - skipping calc-yank.el (File already exists)'
  1293.     rm -f _shar_wnt_.tmp
  1294. else
  1295. > _shar_wnt_.tmp
  1296. echo 'x - extracting calc-yank.el (Text)'
  1297. sed 's/^X//' << 'SHAR_EOF' > 'calc-yank.el' &&
  1298. ;; Calculator for GNU Emacs, part II [calc-yank.el]
  1299. ;; Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  1300. ;; Written by Dave Gillespie, daveg@csvax.cs.caltech.edu.
  1301. X
  1302. ;; This file is part of GNU Emacs.
  1303. X
  1304. ;; GNU Emacs is distributed in the hope that it will be useful,
  1305. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  1306. ;; accepts responsibility to anyone for the consequences of using it
  1307. ;; or for whether it serves any particular purpose or works at all,
  1308. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  1309. ;; License for full details.
  1310. X
  1311. ;; Everyone is granted permission to copy, modify and redistribute
  1312. ;; GNU Emacs, but only under the conditions described in the
  1313. ;; GNU Emacs General Public License.   A copy of this license is
  1314. ;; supposed to have been given to you along with GNU Emacs so you
  1315. ;; can know your rights and responsibilities.  It should be in a
  1316. ;; file named COPYING.  Among other things, the copyright notice
  1317. ;; and this notice must be preserved on all copies.
  1318. X
  1319. X
  1320. X
  1321. ;; This file is autoloaded from calc-ext.el.
  1322. (require 'calc-ext)
  1323. X
  1324. (require 'calc-macs)
  1325. X
  1326. (defun calc-Need-calc-yank () nil)
  1327. X
  1328. X
  1329. ;;; Kill ring commands.
  1330. X
  1331. (defun calc-kill (nn &optional no-delete)
  1332. X  (interactive "P")
  1333. X  (if (eq major-mode 'calc-mode)
  1334. X      (calc-wrapper
  1335. X       (calc-force-refresh)
  1336. X       (calc-set-command-flag 'no-align)
  1337. X       (let ((num (max (calc-locate-cursor-element (point)) 1))
  1338. X         (n (prefix-numeric-value nn)))
  1339. X     (if (< n 0)
  1340. X         (progn
  1341. X           (if (eobp)
  1342. X           (setq num (1- num)))
  1343. X           (setq num (- num n)
  1344. X             n (- n))))
  1345. X     (let ((stuff (calc-top-list n (- num n -1))))
  1346. X       (calc-cursor-stack-index num)
  1347. X       (let ((first (point)))
  1348. X         (calc-cursor-stack-index (- num n))
  1349. X         (if (null nn)
  1350. X         (backward-char 1))   ; don't include newline for raw C-k
  1351. X         (copy-region-as-kill first (point))
  1352. X         (if (not no-delete)
  1353. X         (calc-pop-stack n (- num n -1))))
  1354. X       (setq calc-last-kill (cons (car kill-ring) stuff)))))
  1355. X    (kill-line nn))
  1356. )
  1357. X
  1358. (defun calc-force-refresh ()
  1359. X  (if (or calc-executing-macro calc-display-dirty)
  1360. X      (let ((calc-executing-macro nil))
  1361. X    (calc-refresh)))
  1362. )
  1363. X
  1364. (defun calc-locate-cursor-element (pt)
  1365. X  (save-excursion
  1366. X    (goto-char (point-max))
  1367. X    (calc-locate-cursor-scan (- calc-stack-top) calc-stack pt))
  1368. )
  1369. X
  1370. (defun calc-locate-cursor-scan (n stack pt)
  1371. X  (if (or (<= (point) pt)
  1372. X      (null stack))
  1373. X      n
  1374. X    (forward-line (- (nth 1 (car stack))))
  1375. X    (calc-locate-cursor-scan (1+ n) (cdr stack) pt))
  1376. )
  1377. X
  1378. (defun calc-kill-region (top bot &optional no-delete)
  1379. X  (interactive "r")
  1380. X  (if (eq major-mode 'calc-mode)
  1381. X      (calc-wrapper
  1382. X       (calc-force-refresh)
  1383. X       (calc-set-command-flag 'no-align)
  1384. X       (let* ((top-num (calc-locate-cursor-element top))
  1385. X          (bot-num (calc-locate-cursor-element (1- bot)))
  1386. X          (num (- top-num bot-num -1)))
  1387. X     (copy-region-as-kill top bot)
  1388. X     (setq calc-last-kill (cons (car kill-ring)
  1389. X                    (calc-top-list num bot-num)))
  1390. X     (if (not no-delete)
  1391. X         (calc-pop-stack num bot-num))))
  1392. X    (if no-delete
  1393. X    (copy-region-as-kill top bot)
  1394. X      (kill-region top bot)))
  1395. )
  1396. X
  1397. (defun calc-copy-as-kill (n)
  1398. X  (interactive "P")
  1399. X  (calc-kill n t)
  1400. )
  1401. X
  1402. (defun calc-copy-region-as-kill (top bot)
  1403. X  (interactive "r")
  1404. X  (calc-kill-region top bot t)
  1405. )
  1406. X
  1407. ;;; This function uses calc-last-kill if possible to get an exact result,
  1408. ;;; otherwise it just parses the yanked string.
  1409. (defun calc-yank ()
  1410. X  (interactive)
  1411. X  (calc-wrapper
  1412. X   (calc-pop-push-record-list
  1413. X    0 "yank"
  1414. X    (if (eq (car-safe calc-last-kill) (car kill-ring-yank-pointer))
  1415. X    (cdr calc-last-kill)
  1416. X      (if (stringp (car kill-ring-yank-pointer))
  1417. X      (let ((val (math-read-exprs
  1418. X              (calc-clean-newlines (car kill-ring-yank-pointer)))))
  1419. X        (if (eq (car-safe val) 'error)
  1420. X        (progn
  1421. X          (setq val (math-read-exprs (car kill-ring-yank-pointer)))
  1422. X          (if (eq (car-safe val) 'error)
  1423. X              (error "Bad format in yanked data")
  1424. X            val))
  1425. X          val))))))
  1426. )
  1427. X
  1428. (defun calc-clean-newlines (s)
  1429. X  (cond
  1430. X   
  1431. X   ;; Omit leading/trailing whitespace
  1432. X   ((or (string-match "\\`[ \n\r]+\\([^\001]*\\)\\'" s)
  1433. X    (string-match "\\`\\([^\001]*\\)[ \n\r]+\\'" s))
  1434. X    (calc-clean-newlines (math-match-substring s 1)))
  1435. X
  1436. X   ;; Convert newlines to commas
  1437. X   ((string-match "\\`\\(.*\\)[\n\r]+\\([^\001]*\\)\\'" s)
  1438. X    (calc-clean-newlines (concat (math-match-substring s 1) ","
  1439. X                 (math-match-substring s 2))))
  1440. X   
  1441. X   (t s))
  1442. )
  1443. X
  1444. X
  1445. (defun calc-do-grab-region (top bot arg)
  1446. X  (and (memq major-mode '(calc-mode calc-trail-mode))
  1447. X       (error "This command works only in a regular text buffer."))
  1448. X  (let* ((from-buffer (current-buffer))
  1449. X     (calc-was-started (get-buffer-window "*Calculator*"))
  1450. X     (single nil)
  1451. X     data vals pos)
  1452. X    (if arg
  1453. X    (if (consp arg)
  1454. X        (setq single t)
  1455. X      (setq arg (prefix-numeric-value arg))
  1456. X      (if (= arg 0)
  1457. X          (save-excursion
  1458. X        (beginning-of-line)
  1459. X        (setq top (point))
  1460. X        (end-of-line)
  1461. X        (setq bot (point)))
  1462. X        (save-excursion
  1463. X          (setq top (point))
  1464. X          (forward-line arg)
  1465. X          (if (> arg 0)
  1466. X          (setq bot (point))
  1467. X        (setq bot top
  1468. X              top (point)))))))
  1469. X    (setq data (buffer-substring top bot))
  1470. X    (calc)
  1471. X    (if single
  1472. X    (setq vals (math-read-expr data))
  1473. X      (setq vals (math-read-expr (concat "[" data "]")))
  1474. X      (and (eq (car-safe vals) 'vec)
  1475. X       (= (length vals) 2)
  1476. X       (eq (car-safe (nth 1 vals)) 'vec)
  1477. X       (setq vals (nth 1 vals))))
  1478. X    (if (eq (car-safe vals) 'error)
  1479. X    (progn
  1480. X      (if calc-was-started
  1481. X          (pop-to-buffer from-buffer)
  1482. X        (calc-quit t)
  1483. X        (switch-to-buffer from-buffer))
  1484. X      (goto-char top)
  1485. X      (forward-char (+ (nth 1 vals) (if single 0 1)))
  1486. X      (error (nth 2 vals))))
  1487. X    (calc-wrapper
  1488. X     (calc-enter-result 0 "grab" vals)))
  1489. )
  1490. X
  1491. X
  1492. (defun calc-do-grab-rectangle (top bot arg)
  1493. X  (and (memq major-mode '(calc-mode calc-trail-mode))
  1494. X       (error "This command works only in a regular text buffer."))
  1495. X  (let* ((col1 (save-excursion (goto-char top) (current-column)))
  1496. X     (col2 (save-excursion (goto-char bot) (current-column)))
  1497. X     (from-buffer (current-buffer))
  1498. X     (calc-was-started (get-buffer-window "*Calculator*"))
  1499. X     data mat vals lnum pt pos)
  1500. X    (if (= col1 col2)
  1501. X    (save-excursion
  1502. X      (or (= col1 0)
  1503. X          (error "Point and mark must be at beginning of line, or define a rectangle"))
  1504. X      (goto-char top)
  1505. X      (while (< (point) bot)
  1506. X        (setq pt (point))
  1507. X        (forward-line 1)
  1508. X        (setq data (cons (buffer-substring pt (1- (point))) data)))
  1509. X      (setq data (nreverse data)))
  1510. X      (setq data (extract-rectangle top bot)))
  1511. X    (calc)
  1512. X    (setq mat (list 'vec)
  1513. X      lnum 0)
  1514. X    (and arg
  1515. X     (setq arg (if (consp arg) 0 (prefix-numeric-value arg))))
  1516. X    (while data
  1517. X      (if (natnump arg)
  1518. X      (progn
  1519. X        (if (= arg 0)
  1520. X        (setq arg 1000000))
  1521. X        (setq pos 0
  1522. X          vals (list 'vec))
  1523. X        (let ((w (length (car data)))
  1524. X          j v)
  1525. X          (while (< pos w)
  1526. X        (setq j (+ pos arg)
  1527. X              v (if (>= j w)
  1528. X                (math-read-expr (substring (car data) pos))
  1529. X              (math-read-expr (substring (car data) pos j))))
  1530. X        (if (eq (car-safe v) 'error)
  1531. X            (setq vals v w 0)
  1532. X          (setq vals (nconc vals (list v))
  1533. X            pos j)))))
  1534. X    (if (and (null arg)
  1535. X         (string-match "[[{][^][{}]*[]}]" (car data)))
  1536. X        (setq pos (match-beginning 0)
  1537. X          vals (math-read-expr (math-match-substring (car data) 0)))
  1538. X      (let ((s (if (string-match
  1539. X            "\\`\\([0-9]+:[ \t]\\)?\\(.*[^, \t]\\)[, \t]*\\'"
  1540. X            (car data))
  1541. X               (math-match-substring (car data) 2)
  1542. X             (car data))))
  1543. X        (setq pos -1
  1544. X          vals (math-read-expr (concat "[" s "]")))
  1545. X        (if (eq (car-safe vals) 'error)
  1546. X        (let ((v2 (math-read-expr s)))
  1547. X          (or (eq (car-safe v2) 'error)
  1548. X              (setq vals (list 'vec v2))))))))
  1549. X      (if (eq (car-safe vals) 'error)
  1550. X      (progn
  1551. X        (if calc-was-started
  1552. X        (pop-to-buffer from-buffer)
  1553. X          (calc-quit t)
  1554. X          (switch-to-buffer from-buffer))
  1555. X        (goto-char top)
  1556. X        (forward-line lnum)
  1557. X        (forward-char (+ (nth 1 vals) (min col1 col2) pos))
  1558. X        (error (nth 2 vals))))
  1559. X      (setq mat (cons vals mat)
  1560. X        data (cdr data)
  1561. X        lnum (1+ lnum)))
  1562. X    (calc-wrapper
  1563. X     (calc-enter-result 0 "grab" (nreverse mat))))
  1564. )
  1565. X
  1566. X
  1567. (defun calc-copy-to-buffer (nn)
  1568. X  "Copy the top of stack into an editing buffer."
  1569. X  (interactive "P")
  1570. X  (let ((thebuf (and (not (memq major-mode '(calc-mode calc-trail-mode)))
  1571. X             (current-buffer)))
  1572. X    (movept nil)
  1573. X    oldbuf newbuf)
  1574. X    (calc-wrapper
  1575. X     (save-excursion
  1576. X       (calc-force-refresh)
  1577. X       (let ((n (prefix-numeric-value nn))
  1578. X         (eat-lnums calc-line-numbering)
  1579. X         top bot)
  1580. X     (setq oldbuf (current-buffer)
  1581. X           newbuf (or thebuf
  1582. X              (calc-find-writable-buffer (buffer-list) 0)
  1583. X              (calc-find-writable-buffer (buffer-list) 1)
  1584. X              (error "No other buffer")))
  1585. X     (cond ((and (or (null nn)
  1586. X             (consp nn))
  1587. X             (= (calc-substack-height 0)
  1588. X            (1- (calc-substack-height 1))))
  1589. X        (calc-cursor-stack-index 1)
  1590. X        (if (looking-at
  1591. X             (if calc-line-numbering "[0-9]+: *[^ \n]" " *[^ \n]"))
  1592. X            (goto-char (1- (match-end 0))))
  1593. X        (setq eat-lnums nil
  1594. X              top (point))
  1595. X        (calc-cursor-stack-index 0)
  1596. X        (setq bot (1- (point))))
  1597. X           ((> n 0)
  1598. X        (calc-cursor-stack-index n)
  1599. X        (setq top (point))
  1600. X        (calc-cursor-stack-index 0)
  1601. X        (setq bot (- (point)
  1602. X                 (if (eq calc-language 'big) 1 0))))
  1603. X           ((< n 0)
  1604. X        (calc-cursor-stack-index (- n))
  1605. X        (setq top (point))
  1606. X        (calc-cursor-stack-index (1- (- n)))
  1607. X        (setq bot (point)))
  1608. X           (t
  1609. X        (goto-char (point-min))
  1610. X        (forward-line 1)
  1611. X        (setq top (point))
  1612. X        (calc-cursor-stack-index 0)
  1613. X        (setq bot (point))))
  1614. X     (save-excursion
  1615. X       (set-buffer newbuf)
  1616. X       (if (consp nn)
  1617. X           (kill-region (region-beginning) (region-end)))
  1618. X       (push-mark (point) t)
  1619. X       (if (and overwrite-mode (not (consp nn)))
  1620. X           (calc-overwrite-string (save-excursion
  1621. X                    (set-buffer oldbuf)
  1622. X                    (buffer-substring top bot))
  1623. X                      eat-lnums)
  1624. X         (or (bolp) (setq eat-lnums nil))
  1625. X         (insert-buffer-substring oldbuf top bot)
  1626. X         (and eat-lnums
  1627. X          (let ((n 1))
  1628. X            (while (and (> (point) (mark))
  1629. X                (progn
  1630. X                  (forward-line -1)
  1631. X                  (>= (point) (mark))))
  1632. X              (delete-char 4)
  1633. X              (setq n (1+ n)))
  1634. X            (forward-line n))))
  1635. X       (if thebuf (setq movept (point)))
  1636. X       (if (get-buffer-window (current-buffer))
  1637. X           (set-window-point (get-buffer-window (current-buffer))
  1638. X                 (point)))))))
  1639. X    (if movept (goto-char movept))
  1640. X    (and (consp nn)
  1641. X     (not thebuf)
  1642. X     (progn
  1643. X       (calc-quit t)
  1644. X       (switch-to-buffer newbuf))))
  1645. )
  1646. X
  1647. (defun calc-overwrite-string (str eat-lnums)
  1648. X  (if (string-match "\n\\'" str)
  1649. X      (setq str (substring str 0 -1)))
  1650. X  (if eat-lnums
  1651. X      (setq str (substring str 4)))
  1652. X  (if (and (string-match "\\`[-+]?[0-9.]+\\(e-?[0-9]+\\)?\\'" str)
  1653. X       (looking-at "[-+]?[0-9.]+\\(e-?[0-9]+\\)?"))
  1654. X      (progn
  1655. X    (delete-region (point) (match-end 0))
  1656. X    (insert str))
  1657. X    (let ((i 0))
  1658. X      (while (< i (length str))
  1659. X    (if (= (setq last-command-char (aref str i)) ?\n)
  1660. X        (or (= i (1- (length str)))
  1661. X        (let ((pt (point)))
  1662. X          (end-of-line)
  1663. X          (delete-region pt (point))
  1664. X          (if (eobp)
  1665. X              (insert "\n")
  1666. X            (forward-char 1))
  1667. X          (if eat-lnums (setq i (+ i 4)))))
  1668. X      (self-insert-command 1))
  1669. X    (setq i (1+ i)))))
  1670. )
  1671. X
  1672. ;;; First, require that buffer is visible and does not begin with "*"
  1673. ;;; Second, require only that it not begin with "*Calc"
  1674. (defun calc-find-writable-buffer (buf mode)
  1675. X  (and buf
  1676. X       (if (or (string-match "\\`\\( .*\\|\\*Calc.*\\)"
  1677. X                 (buffer-name (car buf)))
  1678. X           (and (= mode 0)
  1679. X            (or (string-match "\\`\\*.*" (buffer-name (car buf)))
  1680. X            (not (get-buffer-window (car buf))))))
  1681. X       (calc-find-writable-buffer (cdr buf) mode)
  1682. X     (car buf)))
  1683. )
  1684. X
  1685. X
  1686. (defun calc-edit (n)
  1687. X  (interactive "p")
  1688. X  (calc-slow-wrapper
  1689. X   (if (eq n 0)
  1690. X       (setq n (calc-stack-size)))
  1691. X   (let* ((flag nil)
  1692. X      (allow-ret (> n 1))
  1693. X      (list (math-showing-full-precision
  1694. X         (mapcar (if (> n 1)
  1695. X                 (function (lambda (x)
  1696. X                     (math-format-flat-expr x 0)))
  1697. X               (function
  1698. X                (lambda (x)
  1699. X                  (if (math-vectorp x) (setq allow-ret t))
  1700. X                  (math-format-nice-expr x (screen-width)))))
  1701. X             (if (> n 0)
  1702. X                 (calc-top-list n)
  1703. X               (calc-top-list 1 (- n)))))))
  1704. X     (calc-edit-mode (list 'calc-finish-stack-edit (or flag n)) allow-ret)
  1705. X     (while list
  1706. X       (insert (car list) "\n")
  1707. X       (setq list (cdr list)))))
  1708. X  (calc-show-edit-buffer)
  1709. )
  1710. X
  1711. (defun calc-alg-edit (str)
  1712. X  (calc-edit-mode '(calc-finish-stack-edit 0))
  1713. X  (calc-show-edit-buffer)
  1714. X  (insert str "\n")
  1715. X  (backward-char 1)
  1716. X  (calc-set-command-flag 'do-edit)
  1717. )
  1718. X
  1719. (defvar calc-edit-mode-map nil "Keymap for use by the calc-edit command.")
  1720. (if calc-edit-mode-map
  1721. X    ()
  1722. X  (setq calc-edit-mode-map (make-sparse-keymap))
  1723. X  (define-key calc-edit-mode-map "\n" 'calc-edit-finish)
  1724. X  (define-key calc-edit-mode-map "\r" 'calc-edit-return)
  1725. X  (define-key calc-edit-mode-map "\C-c\C-c" 'calc-edit-finish)
  1726. )
  1727. X
  1728. (defun calc-edit-mode (&optional handler allow-ret title)
  1729. X  "Calculator editing mode.  Press RET, LFD, or C-c C-c to finish.
  1730. To cancel the edit, simply kill the *Calc Edit* buffer."
  1731. X  (interactive)
  1732. X  (or handler
  1733. X      (error "This command can be used only indirectly through calc-edit."))
  1734. X  (let ((oldbuf (current-buffer))
  1735. X    (buf (get-buffer-create "*Calc Edit*")))
  1736. X    (set-buffer buf)
  1737. X    (kill-all-local-variables)
  1738. X    (use-local-map calc-edit-mode-map)
  1739. X    (setq buffer-read-only nil)
  1740. X    (setq truncate-lines nil)
  1741. X    (setq major-mode 'calc-edit-mode)
  1742. X    (setq mode-name "Calc Edit")
  1743. X    (run-hooks 'calc-edit-mode-hook)
  1744. X    (make-local-variable 'calc-original-buffer)
  1745. X    (setq calc-original-buffer oldbuf)
  1746. X    (make-local-variable 'calc-return-buffer)
  1747. X    (setq calc-return-buffer oldbuf)
  1748. X    (make-local-variable 'calc-one-window)
  1749. X    (setq calc-one-window (and (one-window-p t) pop-up-windows))
  1750. X    (make-local-variable 'calc-edit-handler)
  1751. SHAR_EOF
  1752. true || echo 'restore of calc-yank.el failed'
  1753. fi
  1754. echo 'End of  part 29'
  1755. echo 'File calc-yank.el is continued in part 30'
  1756. echo 30 > _shar_seq_.tmp
  1757. exit 0
  1758. exit 0 # Just in case...
  1759. -- 
  1760. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1761. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1762. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1763. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1764.